#include "TcpConnection.hpp"

#include <sstream>

namespace se {

TcpConnection::TcpConnection(int clientFileDiscriptor) : _socket(clientFileDiscriptor), _socketIO(this->_socket) { }

std::string TcpConnection::receive() {
    static char buffer[1024];
    if (this->_socketIO.read(buffer, sizeof buffer) == 0) {
        this->OnClosed.invoke(shared_from_this());
    }
    return buffer;
}

int TcpConnection::send(const std::string &message) {
    return this->_socketIO.write(message.c_str(), message.size());
}

SocketAddress TcpConnection::getLocalAddress() const {
    struct sockaddr_in address;
    socklen_t addressLength = sizeof address;
    if (::getsockname(this->_socket.getFileDescriptor(), (struct sockaddr *)&address, &addressLength) < 0) {
        ::perror("getsockname");
    }
    return SocketAddress(address);
}

SocketAddress TcpConnection::getRemoteAddress() const {
    struct sockaddr_in address;
    socklen_t addressLength = sizeof address;
    if (::getpeername(this->_socket.getFileDescriptor(), (struct sockaddr *)&address, &addressLength) < 0) {
        ::perror("getsockname");
    }
    return SocketAddress(address);
}

std::string TcpConnection::toString() const {
    std::ostringstream oss;
    oss << this->getLocalAddress().toString() << " -- " << this->getRemoteAddress().toString();
    return oss.str();
}

int TcpConnection::getFileDescriptor() const {
    return this->_socket.getFileDescriptor();
}

}  // namespace se